package com.eliza.base.views.learn.widget

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.net.Uri
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.glance.Button
import androidx.glance.ColorFilter
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.Image
import androidx.glance.ImageProvider
import androidx.glance.LocalContext
import androidx.glance.LocalSize
import androidx.glance.action.clickable
import androidx.glance.appwidget.background
import androidx.glance.appwidget.cornerRadius
import androidx.glance.appwidget.lazy.LazyColumn
import androidx.glance.background
import androidx.glance.color.ColorProvider
import androidx.glance.layout.Alignment
import androidx.glance.layout.Box
import androidx.glance.layout.Column
import androidx.glance.layout.ContentScale
import androidx.glance.layout.Row
import androidx.glance.layout.Spacer
import androidx.glance.layout.fillMaxSize
import androidx.glance.layout.fillMaxWidth
import androidx.glance.layout.padding
import androidx.glance.layout.size
import androidx.glance.layout.wrapContentHeight
import androidx.glance.text.FontFamily
import androidx.glance.text.FontWeight
import androidx.glance.text.Text
import androidx.glance.text.TextAlign
import androidx.glance.text.TextDecoration
import androidx.glance.text.TextStyle
import com.eliza.base.R
import java.text.DecimalFormat
import kotlin.math.roundToInt

object ErrorWidgetX {
    @Composable
    fun Show(context: Context, id: GlanceId) {
        Column {
            Spacer()
            var count by remember {
                mutableIntStateOf(0)
            }
            Text(text = "ErrorWidgetX $count", modifier = GlanceModifier.clickable {
                count = (count + 1) % 2
            })
            when (count) {
                0 -> ErrUIX(context, id)
                1 -> ExactAppWidgetX(context, id)
                2 -> FontDemoContentX(context, id)
                3 -> ImageX(context, id)

            }
        }
    }

    @Composable
    fun ErrUIX(context: Context, id: GlanceId) {
        val repo = ErrorUiAppWidgetConfigurationRepo(context = context, glanceId = id)

        val size = LocalSize.current
        val errorBehavior = repo.getOnErrorBehavior()

        Column(
            modifier = GlanceModifier.fillMaxSize()
                .background(day = Color.LightGray, night = Color.DarkGray)
                .padding(8.dp),
        ) {
            Text(
                "Error UI Demo. Method: $errorBehavior",
                modifier = GlanceModifier.fillMaxWidth().wrapContentHeight(),
                style = TextStyle(
                    fontWeight = FontWeight.Bold,
                    fontSize = 18.sp,
                    textAlign = TextAlign.Center
                )
            )
            Box(
                modifier = GlanceModifier.fillMaxWidth().defaultWeight(),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    "Error UI triggers if width or height reach 400 dp in any orientation.",
                    style = TextStyle(fontWeight = FontWeight.Medium, fontSize = 15.sp)
                )
                check(size.width < 400.dp && size.height < 400.dp) {
                    "Too large now!"
                }
            }
            Text(
                " Current size: ${size.width.value.roundToInt()} dp x " +
                        "${size.height.value.roundToInt()} dp"
            )
        }
    }

    @Composable
    fun ExactAppWidgetX(context: Context, id: GlanceId) {
        Column(
            modifier = GlanceModifier
                .fillMaxSize()
                .background(day = Color.LightGray, night = Color.DarkGray)
                .padding(R.dimen.external_padding)
                .cornerRadius(R.dimen.corner_radius)
        ) {
            Text(
                context.getString(R.string.app_info),
                style = TextStyle(
                    color = ColorProvider(day = Color.DarkGray, night = Color.LightGray),
                    fontWeight = FontWeight.Bold,
                    textDecoration = TextDecoration.Underline
                ),
            )
            val size = LocalSize.current
            val dec = DecimalFormat("#.##")
            val width = dec.format(size.width.value)
            val height = dec.format(size.height.value)
            Text("Current layout: ${width}dp x ${height}dp")
            for (i in 0 until 20) {
                Text("Text $i")
            }
        }
    }

    @Composable
    private fun FontDemoContentX(context: Context, id: GlanceId) {
        // This will reset any time the process is killed, but it isn't important as it's just to
        // showcase different fonts.
        var font by remember { mutableStateOf(FontFamily.Serif) }

        Column() {
            Text("Font Demo Widget")
            Column(modifier = GlanceModifier.fillMaxSize().padding(bottom = 16.dp)) {
                Text(
                    "Font: " + font.family,
                    style = TextStyle(fontSize = 20.sp, fontFamily = FontFamily.SansSerif)
                )
                Spacer(GlanceModifier.size(15.dp))
                Text(
                    "The quick brown fox jumps over the lazy dog.",
                    style = TextStyle(fontSize = 18.sp, fontFamily = font)
                )
                Spacer(GlanceModifier.defaultWeight())
                Button(text = "Toggle font", onClick = {
                    font = when (font) {
                        FontFamily.Serif -> FontFamily.SansSerif
                        FontFamily.SansSerif -> FontFamily.Cursive
                        FontFamily.Cursive -> FontFamily.Monospace
                        FontFamily.Monospace -> FontFamily.Serif
                        else -> FontFamily.SansSerif
                    }
                })
            }
        }
    }

    @Composable
    private fun ImageX(context: Context, id: GlanceId) {
        val ResourceImage: @Composable (title: String, provider: ImageProvider, contentScale: ContentScale, modifier: GlanceModifier) -> Unit =
            { title, provider, contentScale, modifier ->
                Text(
                    text = title,
                    style = TextStyle(androidx.glance.unit.ColorProvider(Color.LightGray), 20.sp)
                )
                Image(
                    provider = provider,
                    contentDescription = "Content Scale image sample (value: ${contentScale})",
                    contentScale = contentScale,
                    modifier = modifier
                )
            }
        val context = LocalContext.current
        var shouldTintHeaderIcon by remember { mutableStateOf(true) }

        Row(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalAlignment = Alignment.CenterVertically,
            modifier = GlanceModifier.fillMaxWidth().background(Color.Gray)
        ) {
            // Demonstrates toggling application of color filter on an image
            Image(
                provider = androidx.glance.ImageProvider(R.drawable.bar_point),
                contentDescription = null,
                colorFilter = if (shouldTintHeaderIcon) {
                    ColorFilter.tint(
                        ColorProvider(day = Color.Green, night = Color.Blue)
                    )
                } else {
                    null
                },
                modifier = GlanceModifier.clickable {
                    shouldTintHeaderIcon = !shouldTintHeaderIcon
                }
            )
            Text(
                text = context.getString(R.string.app_auth),
                modifier = GlanceModifier.padding(8.dp),
            )
        }

        //===============
        fun makeBitmap(): Bitmap {
            val w = 100f
            val h = 100f
            val bmp = Bitmap.createBitmap(w.toInt(), h.toInt(), Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bmp)
            val paint = Paint()

            paint.setColor(Color.Black.toArgb()) // transparent
            canvas.drawRect(0f, 0f, w, h, paint)
            paint.setColor(Color.White.toArgb()) // Opaque
            canvas.drawCircle(w / 2f, h / 2f, w / 3f, paint)

            return bmp
        }

        LazyColumn(GlanceModifier.fillMaxSize()) {
            item {

                ResourceImage(
                    "R.drawable",
                    androidx.glance.ImageProvider(R.drawable.tou_xiang),
                    ContentScale(1),
                    GlanceModifier
                )
            }
            item {

                ResourceImage(
                    "Bitmap.createBitmap",
                    ImageProvider(makeBitmap()),
                    ContentScale.Crop,
                    GlanceModifier
                )
            }

            fun canvasBitmap(outputCanvasSize: Int, circleColor: Color): Bitmap {
                val bitmap = Bitmap.createBitmap(
                    outputCanvasSize,
                    outputCanvasSize,
                    Bitmap.Config.ARGB_8888
                )
                val padding = outputCanvasSize * .05f
                val canvas = Canvas(bitmap)

                fun drawBlueSquare(canvas: Canvas) {
                    val squareSize = outputCanvasSize * (2f / 3f)

                    val x0 = padding
                    val x1 = x0 + squareSize
                    val y0 = (outputCanvasSize - squareSize - padding)
                    val y1 = y0 + squareSize
                    val paint = Paint().apply { setColor(Color.Blue.toArgb()) }
                    canvas.drawRect(x0, y0, x1, y1, paint)
                }

                fun drawCircle(canvas: Canvas) {
                    val r = outputCanvasSize * (1f / 3f)
                    val cx = outputCanvasSize - r - padding
                    val cy = r + padding

                    val paint = Paint().apply { setColor(circleColor.toArgb()) }
                    canvas.drawCircle(cx, cy, r, paint)
                }

                drawBlueSquare(canvas)
                drawCircle(canvas)

                return bitmap
            }

            val bitmap = canvasBitmap(200, circleColor = Color.Red)
            item {

                ResourceImage(
                    "Bitmap.createBitmap",
                    ImageProvider(bitmap),
                    ContentScale.Fit,
                    GlanceModifier
                )
            }
            item {
                ResourceImage(
                    "Bitmap.createBitmap",
                    androidx.glance.appwidget.ImageProvider(
                        Uri.parse("https://c-ssl.duitang.com/uploads/blog/202112/27/20211227155606_d2be0.jpeg")
                    ),
                    ContentScale.Fit,
                    GlanceModifier
                )
            }
        }
    }
}